var map;
var layer;
var style_map
var WGS_PROJECTION = new OpenLayers.Projection("EPSG:4326");
var SPHERICAL_MERCATOR_PROJECTION = new OpenLayers.Projection("EPSG:900913");
var features = new Array();
var points;
var f;
var ratings;

var radius;

var time_min = 0;
var time_max;
var distance_max;
var distance_min = 0;
var space_percentage;
var time_percentage;
var index_percentage;
var rating = 0;

function init() {
    map = new OpenLayers.Map({
		displayProjection: WGS_PROJECTION
	});
}

function add_layer(layerName){
    if(layer)
        map.removeLayer(map.layers[0])
	
    layer = new OpenLayers.Layer.Vector(layerName, {
        styleMap: style_map
    });
    map.addLayer(layer);
}

//in home.html
function add_reports(reports) {
	var format = new OpenLayers.Format.GeoJSON({internalProjection: SPHERICAL_MERCATOR_PROJECTION, externalProjection: WGS_PROJECTION});
	layer.addFeatures(format.read(reports));
}

function get_number_of_nearby_points(point){
    nearby_points = 0;
    for(var i=0; i<points.length; i++){
        distance = point.distanceTo(points[i])
        if(distance!=0 && distance <= radius)
            nearby_points++;
    }
    return nearby_points;
}

function get_space_difference(point){
    total_distance = 0;
    //number of points within radius
    number_of_points = 0;
    
    for(var i=0; i<points.length; i++){
        distance = point.distanceTo(points[i])
        if(distance!=0 && distance <= radius){
            number_of_points++;
            total_distance += distance;
        }
    }
    if(number_of_points)
        return total_distance/number_of_points;
    else
        return 0;
}

function get_index_difference(point, point_index){
    total_index_difference = 0;
    //number of points within radius
    number_of_points = 0;
    //points within radius
    nearby_points = new Array();
    nearby_features = new Array();
    
    //determine nearby points
    for(var i=0; i<points.length; i++){
        distance = point.distanceTo(points[i])
        if(distance!=0 && distance <= radius){
            nearby_points.push(i)
        }
    }
    
    //get features corresponding to nearby points
    for(var i=0; i<nearby_points.length; i++){
        nearby_features.push(features[nearby_points[i]]);
    }
    
    //compute total index difference for all nearby points
    for(var i=0; i<nearby_features.length; i++){
        difference = Math.abs(nearby_features[i].attributes.index - point_index) 
        total_index_difference += difference;
    }
    
    number_of_points = nearby_features.length
    if(number_of_points)
        return total_index_difference/number_of_points;
    else
        return 0;
}

function get_time_difference(point, point_date_time){
    total_time_difference = 0;
    //number of points within radius
    number_of_points = 0;
    //points within radius
    nearby_points = new Array();
    nearby_features = new Array();
    
    //determine nearby points
    for(var i=0; i<points.length; i++){
        distance = point.distanceTo(points[i])
        if(distance!=0 && distance <= radius){
            nearby_points.push(i)
        }
    }
    
    //get features corresponding to nearby points
    for(var i=0; i<nearby_points.length; i++){
        nearby_features.push(features[nearby_points[i]]);
    }
    
    //compute total time difference for all nearby points
    for(var i=0; i<nearby_features.length; i++){
        a = stringToDate(nearby_features[i].attributes.date_event);
        b = stringToDate(point_date_time);
        difference_in_milliseconds = Math.abs(a.getTime() - b.getTime()); 
        days = Math.ceil(difference_in_milliseconds / 1000 / 60 / 60 / 24);
        total_time_difference += days;
    }
    
    number_of_points = nearby_features.length
    if(number_of_points)
        return total_time_difference/number_of_points;
    else
        return 0;
}

function stringToDate(s) {
  var dateParts = s.split(' ')[0].split('-'); 
  var timeParts = s.split(' ')[1].split(':');
  var d = new Date(dateParts[0], --dateParts[1], dateParts[2]);
  d.setHours(timeParts[0], timeParts[1], timeParts[2]);

  return d;
}

function prepare_points(){
    features = map.layers[0].features;
    points = new Array();
    
    //determine points within that layer
    for(var i=0; i<features.length; i++){
        points.push(features[i].geometry);
    }
}

function validate_reports(){
    prepare_points();
    f = new Array();
    distance_max = parseFloat(radius);
    index_max = Math.round(features[0].attributes.index/features[0].attributes.severity)-1;
    ratings = new Array();
    
    for(var i=0; i<features.length; i++){
        var validation_details = new Array();
        
        num_points = get_number_of_nearby_points(points[i]);
        validation_details.push(num_points);
        
        space_difference = get_space_difference(points[i]);
        validation_details.push(space_difference);
        if(space_difference <= distance_max && space_difference)
            rate = 1 - (space_difference - distance_min)/(distance_max-distance_min)
        else
            rate = 0
        space_rate = rate*space_percentage;
        
        time_difference = get_time_difference(points[i], features[i].attributes.date_event);
        validation_details.push(time_difference);
        if(time_difference <= time_max && time_difference)
            rate = 1 - (time_difference - time_min)/(time_max-time_min)
        else
            rate = 0
        time_rate = rate*time_percentage;
        
        index_difference = get_index_difference(points[i], features[i].attributes.index);
        validation_details.push(index_difference);
        if(index_difference)
            rate = 1 - (index_difference - 0)/(index_max-0)
        else
            rate = 0
        index_rate = rate*index_percentage;
        
        rating = space_rate + time_rate + index_rate;
        ratings.push(rating)
        validation_details.push(rating);
        
        f.push(validation_details)
    }
}

function display_reports(){
    text = '';
    ratings.sort(function(a,b){return b - a});
    for(var i=0; i<f.length; i++){
            text +=     '<div class="report">' +
                            '<div><h3>' + features[i].attributes.title + '</h3></div>' +
                            '<div class="gen_desc">' +
                                '<div>date: ' + features[i].attributes.date_event + '</div>' +
                                '<div>description: ' + features[i].attributes.description + '</div>' +
                                '<div>' + features[i].attributes.index_name + ': ' + features[i].attributes.index + '</div>' +
                            '</div>' +
                            '<div class="validation_desc">' +
                                '<div>nearby points: ' + f[i][0] + '</div>' +
                                '<div>space difference: ' + f[i][1].toFixed(2) + ' meters</div>' +
                                '<div>time difference: ' + f[i][2].toFixed(2) + ' days</div>' +
                                '<div>index difference: ' + f[i][3].toFixed(2) + '</div>' +
                             '</div>' + 
                             '<div class="rating_field">rating: <span class="rating">' + f[i][4].toFixed(2) + '</span></div>' +
                             '<div style="clear:both"></div>' +
                        '</div>';
    }
    $("#reports").empty().append(text);  

    $("#details").show();  
}

function create_style(){
    var default_style = new OpenLayers.Style({
        label: '${num_points}',
        fontColor: '#fff',
        fontFamily: 'arial, sans-serif',
        fontSize: '.9em',
        fontWeight: 'bold',
        graphicZIndex: 1,
        pointRadius: '${point_radius}', 
        strokeColor: '#fff',
		strokeWidth: 2.5,
        fillColor: '${color}', 
        fillOpacity: '${severity}'
    },{
        context: {
            num_points: function(feature){
                if(feature.attributes.count > 1)
                    return feature.attributes.count;
                else{
                    return '';
                }
            },
            point_radius: function(feature){ 
                if(feature.attributes.count > 1)
                    return 10*(feature.attributes.count);
                else{
                    return 10;
                }
            } 
        }
    });

	var select_style = new OpenLayers.Style({
		'strokeColor': '#1307f1'
	});

	style_map = new OpenLayers.StyleMap({
		'default': default_style,
		'select': select_style
	});
}

function initialize_map(){
    map = new OpenLayers.Map({
		displayProjection: WGS_PROJECTION,
		restrictedExtent: new OpenLayers.Bounds(116.27, 4.39, 127, 21.53).transform(WGS_PROJECTION, SPHERICAL_MERCATOR_PROJECTION)
	});
    var google = new OpenLayers.Layer.Google('Google Map Layer', {numZoomLevels: 20});
	map.addLayer(google);

	map.setCenter(new OpenLayers.LonLat(121.06850, 14.64866).transform(WGS_PROJECTION, SPHERICAL_MERCATOR_PROJECTION), 15);
}

